﻿// =============================================================================
// TNTTools AttributeInfoReflectiveProperty.cs
// Copyright (c) 2013 TNTTechnologies Inc.
// =============================================================================

#region

using System.Collections;
using System.Reflection;
using System.Text;

using TNTTools.Reflection;
using TNTTools.Reflection.Interfaces;

#endregion

namespace TNTTools{
    /// <summary>
    ///     An example how to overwrite the writing of XML to support attributes such as [XMLIgnore]
    /// </summary>
    public class AttributeInfoReflectiveProperty : ReflectiveProperty{
        public AttributeInfoReflectiveProperty(
            PropertyInfo propertyInfo,
            bool isList,
            Attributes classMarkUpAttributesXml,
            GetterMethod getter,
            SetterMethod setter)
            : base(propertyInfo, isList, classMarkUpAttributesXml, getter, setter){
        }

        public override void Write(StringBuilder stringStream, object source, ISimpleSerializer serializer){
            //object propValue = null;
            string value = null;

            if (this.isList) // is IEnumerable && (propValue is string == false)) //todo: use IList maybe faster as foreach is slow
            {
                int start = 0;

                stringStream.AppendFormat("<{0}>", this.ClassMarkUpAttributesXml.GetXmlArrayAttributeValue(ref start));
                object propValue = this.getter.objectGetter(source);
                foreach (object item in (IEnumerable)propValue){
                    serializer.Serialize(stringStream, item);
                }
                start = 0;
                stringStream.AppendFormat("</{0}>", this.ClassMarkUpAttributesXml.GetXmlArrayAttributeValue(ref start));
            } else{
                int attributeCount = this.ClassMarkUpAttributesXml.Count;
                int startSearch = 0;
                string xmlAttributeValue = this.ClassMarkUpAttributesXml.GetXmlAttributeAttribute(ref startSearch);
                bool isBasic = (serializer.GetAttributeTypes().Contains(this.info.PropertyType));
                if (isBasic){
                    value = this.getter.GetStringValue(this.type, source);
                }

                if (startSearch != -1){
                    serializer.WriteXmlAttribute(stringStream, this, value, xmlAttributeValue);
                } else{
                    if (isBasic){
                        // Write Attribute
                        serializer.WriteXmlAttribute(stringStream, this, value, this.info.Name);
                    } else{
                        object propValue = this.getter.objectGetter(source);

                        if (propValue != null){
                            // we have a Class/Struct so do a xml element
                            serializer.Serialize(stringStream, propValue);
                        }
                    }
                }
            }
        }
    }
}

/*protected override void WriteObjectPropertiesToBuilder(StringBuilder stringStream, object source, ObjectInfo objectInfo)
{
    base.WriteObjectPropertiesToBuilder(stringStream, source, objectInfo);
    /* int propCount = objectInfo.propertyInfo.Count;


     for (int i = 0; i < propCount; ++i)
     {
         //object propValue = null;
         string value = null;
         Attributes attribs = objectInfo.propertyInfo[i].classMarkUpAttributesXml;

         if (attribs.ContainsIgnore)
         {
             continue;
         }


         if (objectInfo.propertyInfo[i].IsList)// is IEnumerable && (propValue is string == false)) //todo: use IList maybe faster as foreach is slow
         {

             int start = 0;

             stringStream.AppendFormat("<{0}>", attribs.GetXmlArrayAttributeValue(ref start));
             object propValue = objectInfo.propertyInfo[i].getter.objectGetter(source);
             foreach (object item in (IEnumerable)propValue)
             {
                 Serialize(stringStream, item);
             }
             start = 0;
             stringStream.AppendFormat("</{0}>", attribs.GetXmlArrayAttributeValue(ref start));
         }
         else
         {
             int attributeCount = attribs.Count;
             int startSearch = 0;
             string xmlAttributeValue = attribs.GetXmlAttributeAttribute(ref startSearch);
             bool isBasic = (basicTypes.Contains(objectInfo.propertyInfo[i].Info.PropertyType));
             if (isBasic)
             {
                 value = objectInfo.propertyInfo[i].getter.GetStringValue(source);
             }

             if (startSearch != -1)
             {
                 // Override the name of the outputted xml attribute
                 // also can signify that something should be an xml attribute not a class.
                 // or you can overide GetAttributeTypes
                 // Write Attribute
                 WriteXmlAttribute(objectInfo.propertyInfo[i], stringStream, value, xmlAttributeValue);

             }
             else
             {
                 if (isBasic)
                 {

                     // Write Attribute
                     WriteXmlAttribute(objectInfo.propertyInfo[i], stringStream, value, objectInfo.propertyInfo[i].Info.Name);
                 }
                 else
                 {
                     object propValue = objectInfo.propertyInfo[i].getter.objectGetter(source);

                     if (propValue != null)
                     {

                         // we have a Class/Struct so do a xml element
                         Serialize(stringStream, propValue);
                     }
                 }
             }
         }
     }
}*/